/*
 * Tezad - Classic puzzle game
 * Copyright 2009 Shayne Riley and Paul Maseberg
 *
 * Tezad is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tezad is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tezad.  If not, see <http://www.gnu.org/licenses/>
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <pezads at gmail dot com>
 */


#ifndef GAMEMINOSTRUCTTEST_H_
#define GAMEMINOSTRUCTTEST_H_

#include "GameMinoStruct.h"
#include "GameMinoState.h"
#include <gtest/gtest.h>
#include <stdexcept>

using ::std::out_of_range;

namespace
{

// The fixture for these tests.
class GameMinoStructTest: public testing::Test
{
};

/**
 * Test for proper use of mino function.
 */
TEST_F(GameMinoStructTest, MinoGood)
{
    // This should be able to be called for each of the bricks and not die.
    for (int i = 0; i < 7; ++i)
    {
        GameMinoStruct::mino(i);
    }
}

/**
 * Test for improper use of mino function.
 */
TEST_F(GameMinoStructTest, MinoBad)
{
    EXPECT_THROW(GameMinoStruct::mino(7), out_of_range)
    << "Should not be able to go outside 0-6 of the available tetrominoes.\n";

    EXPECT_THROW(GameMinoStruct::mino(-1), out_of_range)
    << "Should not be able to go outside 0-6 of the available tetrominoes.\n";
}

/**
 * Test for proper use of bricks function.
 */
TEST_F(GameMinoStructTest, Bricks)
{
    GameMinoStruct const *mino = &GameMinoStruct::mino(0);
    GameMinoState state = GameMinoState(0, 0, 0);
    int outRows[4];
    int outCols[4];
    mino->bricks(state, outRows, outCols);

    // Do a simple check to ensure translation of the minoes are proper.
    GameMinoState translated = GameMinoState(5, 4, 0);
    int transRows[4];
    int transCols[4];
    mino->bricks(translated, transRows, transCols);

    for (int i = 0; i < 4; ++i)
    {
        EXPECT_EQ(5, transRows[i] - outRows[i])
        << "Rows of the mino should be translated by 5.\n";
        EXPECT_EQ(4, transCols[i] - outCols[i])
        << "Columns of the mino should be translated by 4.\n";
    }


    // Checking for the correct shapes would go here if I cared. It is basically
    // copying the data from inside GameMinoStruct anyway.
}

/**
 * Test for proper use of brickStyle function.
 */
TEST_F(GameMinoStructTest, BrickStyle)
{
    // Loops through all of the minos.
    for (int i = 0; i < 7; ++i)
    {
        EXPECT_EQ(i + 1, GameMinoStruct::mino(i).brickStyle())
        << "The brickStyle of the mino should be +1 of the mino type. "
        << "I wish it wasn't though.\n";
    }
}

} // Namespace
#endif /* GAMEMINOSTRUCTTEST_H_ */
